package com.wing.warehouse.service;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.wing.common.exception.BusinessException;
import com.wing.common.utils.JsonResult;
import com.wing.common.utils.UniqueIdGeneratorUtil;
import com.wing.enterprise.feign.EnterpriseClient;
import com.wing.enterprise.res.ReceiptRecord;
import com.wing.enterprise.res.ReceiptRecordDetail;
import com.wing.enums.MoveDownWarehouseItemStatusEnum;
import com.wing.enums.MoveDownWarehouseStatusEnum;
import com.wing.feign.res.ReceiptRecordIFeign;
import com.wing.order.service.DynamicService;
import com.wing.warehouse.dao.MoveDownWarehouseDao;
import com.wing.warehouse.model.entity.MoveDownWarehouse;
import com.wing.warehouse.model.entity.MoveDownWarehouseIterm;
import com.wing.warehouse.model.request.MoveDownWarehouseForm;
import com.wing.warehouse.model.request.MoveDownWarehouseItermForm;
import com.wing.warehouse.model.response.*;
import com.wing.util.BigDecimalUtil;
import com.wing.web.utils.AddUpdateUtil;
import com.wing.web.utils.JwtUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 料箱存储包装编码表-ServiceImpl
 *
 * @author
 */
@Service
@Slf4j
public class MoveDownWarehouseServiceImpl extends ServiceImpl<MoveDownWarehouseDao, MoveDownWarehouse> implements MoveDownWarehouseService {

    @Autowired
    private WarehouseService warehouseService;
    @Autowired
    private DynamicService dynamicService;
    @Autowired
    private MoveDownWarehouseItermService moveDownWarehouseItermService;
    @Autowired
    private ReceiptRecordIFeign receiptRecordIFeign;
    
    @Override
    public List<MoveDownWarehouseVO> list4app(Map<String, Object> params) {
        return baseMapper.list4app(params);
    }

    @Override
    public Page<MoveDownWarehouseVO> pageList4app(Page page, Map<String, Object> params) {
        List<MoveDownWarehouseVO> list = baseMapper.list4app(page, params);
        if (CollectionUtil.isNotEmpty(list)) {
            list.stream().forEach(o-> {
                o.setStatusName(MoveDownWarehouseStatusEnum.getDescByCode(o.getStatus()));
            });
        }
        page.setRecords(list);
        return page;
    }
    
    @Override
    public List<MoveWareHouseKuVO> getNowKuWeiInfo(Map<String, Object> params) {
        List<MoveWareHouseKuVO> list=baseMapper.getNowKuWeiInfo(params);
        return list;
    }

    @Override
    public List<MoveWareHouseKuVO> getNowLiaoXiangInfo(Map<String, Object> params) {
        return baseMapper.getNowLiaoXiangInfo(params);
    }

    @Override
    public JsonResult saveMoveWarehouse(MoveDownWarehouseForm moveDownWarehouseForm) {
        // TODO  获取对应出库仓库  和 入库仓库信息
        //todo 1 查看出库仓库是否是料箱库   料箱库只能去料箱库    相应料箱里面的也要移出
        // 2 获取对应出库库区 对应库位的库存信息是否和   移库数量有超出
        // 3  移动目标表   产品库存列表表：pro_product_inventory   pro_product_inventory_detail   库位存货明细  warehouse_area_sku_iterm     料箱存货明细 pallet_box_sku_iterm
        // 4  移动库的时候  原库的数据采用日志表记录或者详情表中增多几个字段，冗余在明细表中
        WarehouseVO warehouseOut = warehouseService.get4appById(moveDownWarehouseForm.getOutWarehouseId());
        if (ObjectUtil.isNull(warehouseOut)) {
            throw new BusinessException("移出仓库不存在");
        }
        //出库仓库是否料箱库，0是 1否
        if (warehouseOut.getWorkbinStatus() == 0L) {
            WarehouseVO warehouseIn = warehouseService.get4appById(moveDownWarehouseForm.getInWarehouseId());
            //料箱库只能去料箱库
            if (warehouseIn.getWorkbinStatus() == 1L) {
                throw new BusinessException("料箱库只能移动到料箱库");
            }
            //是料箱库同时需要扣减料箱存货明细之后 再重新存入目标数据
            List<MoveDownWarehouseItermForm> moveWarehouseItermFormList = moveDownWarehouseForm.getMoveDownWarehouseItermFormList();
            if (CollectionUtil.isEmpty(moveWarehouseItermFormList)) {
                throw new BusinessException("请添加移库下货明细");
            }
            moveWarehouseItermFormList.stream().forEach(o-> {
                //1.未全部移出，扣减数量
//                if () {
//                    PalletBoxSkuItermForm
//                    enterpriseClient.updatePalletBoxSkuIterm();

//                }
                //2.全部移出，删除库存
            });

        } else {
            //不是料箱库就直接扣减 库位存货明细库存  原数据是否删除 还是只是扣减库存就好 ？？？  再重新存入目标数据
            

        }

      return JsonResult.success();
    }

    @Override
    public int add(MoveDownWarehouseForm moveDownWarehouseForm) {
        log.info("MoveDownWarehouseService.add：{}", JSON.toJSONString(moveDownWarehouseForm));
        //校验
        addValidate(moveDownWarehouseForm);
        //添加调拨任务
        MoveDownWarehouse moveDownWarehouse = new MoveDownWarehouse();
        BeanUtil.copyProperties(moveDownWarehouseForm, moveDownWarehouse);
        SimpleDateFormat simpleDateFormat=new SimpleDateFormat("yyyyMMdd");
        String code = dynamicService.getDayMaxCode("move_down_number", "war_move_down_warehouse");
        String day = simpleDateFormat.format(new Date());
        moveDownWarehouse.setMoveDownNumber("YK"+day+code);
        List<MoveDownWarehouseItermForm> moveDownWarehouseItermFormList = moveDownWarehouseForm.getMoveDownWarehouseItermFormList();
        moveDownWarehouse.setSkuNum(moveDownWarehouseItermFormList.size());
        moveDownWarehouse.setStatus(MoveDownWarehouseStatusEnum.wait_out.getCode());
        AddUpdateUtil.fillInsertInfo(moveDownWarehouse);
        int count = baseMapper.insert(moveDownWarehouse);
        if (count > 0) {
            //明细
            List<MoveDownWarehouseIterm> moveDownWarehouseItermList = new ArrayList<>();
            moveDownWarehouseItermFormList.stream().forEach(o -> {
                int i = 1;
                MoveDownWarehouseIterm moveDownWarehouseIterm = new MoveDownWarehouseIterm();
                BeanUtil.copyProperties(o, moveDownWarehouseIterm);
                moveDownWarehouseIterm.setMoveDownNumber(moveDownWarehouse.getMoveDownNumber());
                moveDownWarehouseIterm.setMoveDownItermNumber(moveDownWarehouse.getMoveDownNumber().concat("-").concat(String.valueOf(i++)));
                moveDownWarehouseIterm.setStatus(MoveDownWarehouseItemStatusEnum.wait_out.getCode());
                moveDownWarehouseIterm.setOutWarehouseId(moveDownWarehouse.getOutWarehouseId());
                moveDownWarehouseIterm.setInWarehouseId(moveDownWarehouse.getInWarehouseId());
                AddUpdateUtil.fillInsertInfo(moveDownWarehouseIterm);
                moveDownWarehouseItermList.add(moveDownWarehouseIterm);
            });
            moveDownWarehouseItermService.saveBatch(moveDownWarehouseItermList);
            /**添加出库任务*/
            ReceiptRecord receiptRecord = ReceiptRecord.builder()
                .auditPerson(JwtUtils.getLoginUserId())
                .auditPersonName(JwtUtils.getLoginUsername())
                .auditResult("2")//出库已审核
                .creator(JwtUtils.getLoginUserId())
                .createTime(new Date())
                .creatorName(JwtUtils.getLoginUsername())
                .inventoryTypeId(2L)//调拨出库
                .workOrderId(moveDownWarehouse.getId())//放入调拨任务id
                .receiptWarehouse(moveDownWarehouse.getOutWarehouseId().longValue())
                .build();
            String taskNo = UniqueIdGeneratorUtil.generateUniqueId("LL", "yyyyMMdd", 1000, 9999);
            receiptRecord.setCode(taskNo);
            receiptRecord.setStatus(2);//待领料
            receiptRecord.setRemark("调拨任务自动生成");
            ReceiptRecord receiptRecordAdd = receiptRecordIFeign.saveReceiptRecord(receiptRecord);
            //出库任务明细
            List<ReceiptRecordDetail> receiptRecordDetails = new ArrayList<>();
            moveDownWarehouseItermFormList.stream().forEach(o -> {
                ReceiptRecordDetail receiptRecordDetail = new ReceiptRecordDetail();
                receiptRecordDetail.setReceiptRecordId(receiptRecordAdd.getId());
                receiptRecordDetail.setProductDetailId(o.getSkuId());
                receiptRecordDetail.setReceiptNum(o.getMoveNum());
                receiptRecordDetail.setRemark("调拨任务自动生成");
                receiptRecordDetail.setCreateTime(new Date());
                receiptRecordDetail.setFlagStatus("1");
                receiptRecordDetails.add(receiptRecordDetail);
            });
            receiptRecordIFeign.saveReceiptRecordDetail(receiptRecordDetails);
        }
        return count;
    }

    private void addValidate(MoveDownWarehouseForm moveDownWarehouseForm) {
        if (ObjectUtil.isNull(moveDownWarehouseForm)) {
            throw new BusinessException("请添加调拨任务");
        }
        List<MoveDownWarehouseItermForm> moveDownWarehouseItermFormList = moveDownWarehouseForm.getMoveDownWarehouseItermFormList();
        if (CollectionUtil.isEmpty(moveDownWarehouseItermFormList)) {
            throw new BusinessException("请添加调拨任务明细");
        }
        
        if (moveDownWarehouseItermFormList.stream()
            .collect(Collectors.groupingBy(MoveDownWarehouseItermForm::getSkuCode))
            .values().stream()
            .anyMatch(group -> group.size() > 1)) {
            throw new BusinessException("同一个物料只能有一条明细");
        }
        moveDownWarehouseItermFormList.stream().forEach(o-> {
            if (o.getMoveNum().compareTo(BigDecimal.ZERO) <= 0) {
                throw new BusinessException("移库数量必须大于0");
            }
            Map<String, Object> goodsParams = new HashMap<>();
            goodsParams.put("outWarehouseId", moveDownWarehouseForm.getOutWarehouseId());
            goodsParams.put("skuId", o.getSkuId());
            Page<MoveGoodsListVO> goodsListPage = getGoodsList(new Page<>(1, 9999), goodsParams);
            List<MoveGoodsListVO> goodsList = goodsListPage.getRecords();
            if (CollectionUtil.isEmpty(goodsList)) {
                throw new BusinessException("【" + o.getSkuCode() + "】" + "出库物料不存在");
            }
            if (goodsList.size() > 1) {
                throw new BusinessException("【" + o.getSkuCode() + "】" + "物料重复");
            }
            MoveGoodsListVO moveGoodsListVO = goodsList.get(0);
            if (o.getMoveNum().compareTo(moveGoodsListVO.getFirstNum()) > 0) {
                throw new BusinessException("【" + o.getSkuCode() + "】" + "移库数量超出在库数量");
            }
        });
    }
    
    @Override
    public Page<MoveGoodsListVO> getGoodsList(Page<MoveGoodsListVO> page, Map<String, Object> params) {
        List<MoveGoodsListVO> list = baseMapper.getGoodsList(page, params);
        page.setRecords(list);
        return page;
    }
    
    @Override
    public int cancel(Long id) {
        MoveDownWarehouse moveDownWarehouse = baseMapper.selectById(id);
        if (ObjectUtil.isNull(moveDownWarehouse)) {
            throw new BusinessException("调拨任务不存在");
        }
        if (moveDownWarehouse.getStatus() > MoveDownWarehouseStatusEnum.wait_out.getCode()) {
            throw new BusinessException("已出库，取消失败");
        }
        //更新主表
        MoveDownWarehouse moveDownWarehouseUpdate = new MoveDownWarehouse();
        moveDownWarehouseUpdate.setId(id);
        moveDownWarehouseUpdate.setStatus(MoveDownWarehouseStatusEnum.cancel.getCode());
        int count = baseMapper.updateById(moveDownWarehouseUpdate);
        //更新明细
        if (count > 0) {
            UpdateWrapper updateWrapper = new UpdateWrapper();
            updateWrapper.eq("move_down_number", moveDownWarehouse.getMoveDownNumber());
            updateWrapper.set("status", MoveDownWarehouseItemStatusEnum.cancel.getCode());
            moveDownWarehouseItermService.update(updateWrapper);
        }
        return count;
    }

    @Override
    public MoveDownWarehouseVO getDetailById(Long id) {
        MoveDownWarehouseVO moveDownWarehouseVO = baseMapper.get4appById(id);
        if (ObjectUtil.isNotEmpty(moveDownWarehouseVO)) {
            moveDownWarehouseVO.setStatusName(MoveDownWarehouseStatusEnum.getDescByCode(moveDownWarehouseVO.getStatus()));
            Map<String, Object> itemParams = new HashMap<>();
            itemParams.put("moveDownNumber", moveDownWarehouseVO.getMoveDownNumber());
            List<MoveDownWarehouseItermVO> moveDownWarehouseItermListVO = moveDownWarehouseItermService.list4app(itemParams);
            if (CollectionUtil.isNotEmpty(moveDownWarehouseItermListVO)) {
                moveDownWarehouseItermListVO.stream().forEach(o-> {
                    o.setStatusName(MoveDownWarehouseStatusEnum.getDescByCode(o.getStatus()));
                    o.setLeaveNum(BigDecimalUtil.defaultIfNull(o.getFirstNum()).subtract(BigDecimalUtil.defaultIfNull(o.getMoveNum())));
                });
                moveDownWarehouseVO.setMoveDownWarehouseItermVOList(moveDownWarehouseItermListVO);
            }
        }
        return moveDownWarehouseVO;
    }

}
